package com.maimang.platform.dsp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maimang.platform.common.utils.DateUtils;
import com.maimang.platform.dsp.constant.AdvertiserApi;
import com.maimang.platform.dsp.entity.AdvertiserIds;
import com.maimang.platform.dsp.entity.FundDaily;
import com.maimang.platform.dsp.mapper.FundDailyMapper;
import com.maimang.platform.dsp.service.AccessTokenService;
import com.maimang.platform.dsp.service.AdvertiserIdsService;
import com.maimang.platform.dsp.service.FundDailyService;
import com.maimang.platform.dsp.utils.ApiService;
import com.maimang.platform.lang.ConvertUtils;
import com.maimang.platform.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

/**
 * @author Rocky
 * @version 1.0.0
 * @classname FundDailyServiceImpl
 * @description <br>账户日流水 服务层实现</br>
 * @date 2019-07-31 10:07:36
 * @email jintaozhao@qq.com
 */
@Service
public class FundDailyServiceImpl implements FundDailyService {

	@Autowired
	private FundDailyMapper fundDailyMapper;

	@Autowired
	private ApiService apiService;

	@Autowired
	private AdvertiserIdsService advertiserIdsService;

	@Autowired
	private AccessTokenService accessTokenService;

	/**
	 * 查询账户日流水信息
	 *
	 * @param advertiserId 账户日流水ID
	 * @return 账户日流水信息
	 */
	@Override
	public FundDaily selectFundDailyById(Long advertiserId) {
		return fundDailyMapper.selectFundDailyById(advertiserId);
	}

	/**
	 * 查询账户日流水列表
	 *
	 * @param fundDaily 账户日流水信息
	 * @return 账户日流水集合
	 */
	@Override
	public List<FundDaily> selectFundDailyList(FundDaily fundDaily) {
		return fundDailyMapper.selectFundDailyList(fundDaily);
	}

	/**
	 * 根据广告主id查询账户日流水
	 *
	 * @param advertiserId 广告主id
	 * @return
	 */
	@Override
	public List<FundDaily> selectDailyByAdvertiserId(Long advertiserId) {
		if (StringUtils.isNull(advertiserId))
			return null;
		FundDaily fundDaily = new FundDaily();
		fundDaily.setAdvertiserId(advertiserId);
		return fundDailyMapper.selectFundDailyList(fundDaily);
	}

	/**
	 * 同步账户日流水
	 *
	 * @param advertiserId 广告主id
	 */
	@Override
	public void syncFundDaily(String advertiserId) {

		List<AdvertiserIds> idsList = advertiserIdsService.selectAdvertiserIds(Long.valueOf(advertiserId));

		double total = idsList.size();
		int pageSize = 2000;
		double totalPage = Math.ceil(total / pageSize);
		for (int i = 0; i < totalPage; i++) {
			int beginIndex = i * pageSize;
			int endIndex = (int) Math.min((i + 1) * pageSize, total);

			Executors.newCachedThreadPool().execute(() -> {
				List<AdvertiserIds> advertiserIdsList = idsList.subList(beginIndex, endIndex);

				String endDate = DateUtils.getDate();
				String startDate = DateUtils.getBeforeDayString(endDate, 7);
				for (int j = 0; j < advertiserIdsList.size(); j++) {
					AdvertiserIds advertiser = advertiserIdsList.get(j);
					getFundDaily(advertiser.getId(), startDate, endDate, 1, 10);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	/**
	 * 查询账户日流水列表
	 *
	 * @param advertiserId 广告主id
	 * @return 账户日流水集合
	 */
	@Override
	public List<FundDaily> findFundDailyList(Long advertiserId) {
		FundDaily fundDaily = null;
		if (advertiserId != null) {
			fundDaily = new FundDaily();
			fundDaily.setAdvertiserId(advertiserId);
		}
		return fundDailyMapper.selectFundDailyList(fundDaily);
	}

	/**
	 * 新增账户日流水
	 *
	 * @param fundDaily 账户日流水信息
	 * @return 结果
	 */
	@Override
	public int insertFundDaily(FundDaily fundDaily) {
		return fundDailyMapper.insertFundDaily(fundDaily);
	}

	/**
	 * 修改账户日流水
	 *
	 * @param fundDaily 账户日流水信息
	 * @return 结果
	 */
	@Override
	public int updateFundDaily(FundDaily fundDaily) {
		return fundDailyMapper.updateFundDaily(fundDaily);
	}

	/**
	 * 删除账户日流水对象
	 *
	 * @param ids 需要删除的数据ID
	 * @return 结果
	 */
	@Override
	public int deleteFundDailyByIds(String ids) {
		return fundDailyMapper.deleteFundDailyByIds(ConvertUtils.toStrArray(ids));
	}

	/**
	 * 查询账号日流水
	 *
	 * @param advertiserId 广告主ID
	 * @param startDate    开始日期
	 * @param endDate      结束日期
	 * @param page
	 * @param pageSize
	 * @return
	 */
	@Override
	public List<FundDaily> getFundDaily(Long advertiserId, String startDate, String endDate, int page, int pageSize) {
		if (advertiserId == null)
			return null;
		List<FundDaily> fundDailyList = new ArrayList<>();
		Map param = new HashMap();
		if (StringUtils.isNotNull(advertiserId)) {
			param.put("advertiser_id", advertiserId);
		}
		if (StringUtils.isNotEmpty(startDate)) {
			param.put("start_date", startDate);
		}
		if (StringUtils.isNotEmpty(endDate)) {
			param.put("end_date", endDate);
		}
		if (page >= 0) {
			param.put("page", page);
		}
		if (pageSize > 0) {
			param.put("page_size", pageSize);
		}
		String accessToken = accessTokenService.accessToken();
		JSONObject result = apiService.sendGet(AdvertiserApi.FUND_DAILY, accessToken, param);
		if (result != null) {
			if (result.getInteger("code") == 0) {
				JSONObject data = result.getJSONObject("data");
				if (data != null) {
					JSONArray list = data.getJSONArray("list");

					fundDailyList = list.toJavaList(FundDaily.class);

					if (fundDailyList.size() > 0) {
						// 保存到数据库中
						for (FundDaily fundDaily : fundDailyList) {
							// 先删除记录
							fundDailyMapper.deleteFundDailyById(fundDaily.getAdvertiserId(), fundDaily.getDate());
							// 重新插入
							fundDailyMapper.insertFundDaily(fundDaily);
						}
					}

					JSONObject pageInfo = data.getJSONObject("page_info");
					if (StringUtils.isNotNull(pageInfo)) {
						int current_page = pageInfo.getIntValue("page");
						int page_size = pageInfo.getIntValue("page_size");
						int total_page = pageInfo.getIntValue("total_page");
						if (current_page < total_page) {
							try {
								Thread.sleep(1000);
								getFundDaily(advertiserId, startDate, endDate, current_page + 1, page_size);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		}
		return fundDailyList;
	}

}
